import { defineStore } from 'pinia';
import { nextTick, reactive } from 'vue';
import {EventSourcePolyfill} from 'event-source-polyfill';
const { VITE_API_URL } = import.meta.env;

import { taskStatus } from '/@/enums/terminalEnum';
import type { Terminal } from '/@/enums/terminalEnum';
import { timeFormat } from '/@/utils/formatTime';
import { randomNum } from '/@/utils/util';
import { Local } from '/@/utils/storage';
import useConfigStore from '/@/stores/config';

declare global {
	interface Window {
		eventSource: EventSource | null;
	}
}

export const useTerminal = defineStore(
	'terminal',
	() => {
		const state: Terminal = reactive({
			taskList: [],
			showFooter: true,
			autoCleanCompleteTask: true,
		});

		const configStore = useConfigStore();

		// 初始化终端状态
		function initializeTasks() {
			state.taskList.forEach(task => {
				if (task.status === taskStatus.Connecting || task.status === taskStatus.Executing) {
					task.status = taskStatus.Unknown;
				}
			});
		}

		// 更新自动清理完成任务的设置
		function updateAutoCleanSetting(value: boolean) {
			state.autoCleanCompleteTask = value;
		}

		// 更新任务状态
		function updateTaskStatus(taskIndex: number, status: number) {
			state.taskList[taskIndex].status = status;
			if (status === taskStatus.Failed || status === taskStatus.Unknown) {
				toggleTaskMessage(taskIndex, true);
			}
		}

		// 处理任务完成回调
		function handleTaskCompletion(taskIndex: number) {
			const task = state.taskList[taskIndex];
			if (typeof task.callback !== 'function') return;

			const status = task.status;
			if (status === taskStatus.Failed || status === taskStatus.Unknown) {
				task.callback(taskStatus.Failed);
			} else if (status === taskStatus.Success) {
				task.callback(taskStatus.Success);
			}
		}

		// 切换任务消息显示状态
		function toggleTaskMessage(taskIndex: number, value = !state.taskList[taskIndex].showMessage) {
			state.taskList[taskIndex].showMessage = value;
		}

		// 添加任务消息
		function appendTaskMessage(taskIndex: number, message: string) {
			state.taskList[taskIndex].message = state.taskList[taskIndex].message.concat(message);
			nextTick(() => {
				scrollMessageToBottom(state.taskList[taskIndex].uuid);
			});
		}

		// 添加新任务
		function addNewTask(command: string, extend = '', callback: Function = () => {}) {
			const newTask = {
				uuid: String(randomNum(0, 1000)),
				createTime: timeFormat(),
				status: taskStatus.Waiting,
				command,
				message: [],
				showMessage: false,
				extend,
				callback,
			};

			state.taskList = state.taskList.concat(newTask);

			if (state.autoCleanCompleteTask) {
				clearCompletedTasks();
			}

			startNextTask();
		}

		// 删除任务
		function removeTask(taskIndex: number) {
			const task = state.taskList[taskIndex];
			if (task.status !== taskStatus.Connecting && task.status !== taskStatus.Executing) {
				state.taskList.splice(taskIndex, 1);
			}
			startNextTask();
		}

		// 清空所有任务
		function clearAllTasks() {
			state.taskList = [];
			startNextTask();
		}

		// 启动下一个任务
		function startNextTask() {
			let nextTaskIndex = null;

			for (const [index, task] of state.taskList.entries()) {
				if (task.status === taskStatus.Waiting) {
					nextTaskIndex = index;
					break;
				}
				if (task.status === taskStatus.Connecting || task.status === taskStatus.Executing) {
					break;
				}
			}

			if (nextTaskIndex !== null) {
				updateTaskStatus(nextTaskIndex, taskStatus.Connecting);
				initializeEventSource(nextTaskIndex);
			}
		}

		var eventSourceClient = null;

		// 初始化 EventSource
		function initializeEventSource(taskIndex: number) {
			const task = state.taskList[taskIndex];
			let url = `${VITE_API_URL}`;
			let is_command = configStore.sysConfig?.workerman_terminal_status;

			if(is_command) {
				const params = new URLSearchParams({
					command: task.command,
					uuid: task.uuid,
					extend: task.extend,
					token: Local.get('token'),
					server: '1',
				});

				url += `/terminal?${params.toString()}`;

				eventSourceClient = new EventSource(url);
			} else {
				const params = new URLSearchParams({
					command: task.command,
					uuid: task.uuid,
					extend: task.extend,
					server: '1',
				});

				url += `/admin/addons/manage/terminal?${params.toString()}`;

				eventSourceClient = new EventSourcePolyfill(url, {
					headers: {
						'Authorization': Local.get('token')
					}
				});
			}

			eventSourceClient.onmessage = (event) => {
				const data = JSON.parse(event.data);
				if (!data?.data) return;

				const currentTaskIndex = findTaskByUuid(data.uuid);
				if (currentTaskIndex === false) return;

				handleEventSourceMessage(data, currentTaskIndex);
			};

			eventSourceClient.onerror = () => {
				eventSourceClient?.close();
				const currentTaskIndex = findTaskByGuess(taskIndex);
				if (currentTaskIndex === false) return;
				
				updateTaskStatus(currentTaskIndex, taskStatus.Failed);
				handleTaskCompletion(currentTaskIndex);
			};
		}

		// 处理 EventSource 消息
		function handleEventSourceMessage(data: any, taskIndex: number) {
			switch (data.type) {
				case 'exec_error':
					updateTaskStatus(taskIndex, taskStatus.Failed);
					eventSourceClient?.close();
					handleTaskCompletion(taskIndex);
					startNextTask();
					break;
				case 'exec_complete':
					eventSourceClient?.close();
					if (state.taskList[taskIndex].status !== taskStatus.Success) {
						updateTaskStatus(taskIndex, taskStatus.Failed);
					}
					handleTaskCompletion(taskIndex);
					startNextTask();
					break;
				case 'link_success':
					updateTaskStatus(taskIndex, taskStatus.Executing);
					break;
				case 'exec_success':
					updateTaskStatus(taskIndex, taskStatus.Success);
					break;
				default:
					appendTaskMessage(taskIndex, data.data);
			}
		}

		// 重试任务
		function retryTask(taskIndex: number) {
			state.taskList[taskIndex].message = [];
			updateTaskStatus(taskIndex, taskStatus.Waiting);
			startNextTask();
		}

		// 清理已完成的任务
		function clearCompletedTasks() {
			state.taskList = state.taskList.filter(task => task.status !== taskStatus.Success);
		}

		// 通过 UUID 查找任务
		function findTaskByUuid(uuid: string) {
			const index = state.taskList.findIndex(task => task.uuid === uuid);
			return index === -1 ? false : index;
		}

		// 通过索引查找任务
		function findTaskByGuess(index: number) {
			if (!state.taskList[index]) {
				const activeTaskIndex = state.taskList.findIndex(
					task => task.status === taskStatus.Connecting || task.status === taskStatus.Executing
				);
				return activeTaskIndex === -1 ? false : activeTaskIndex;
			}
			return index;
		}

		// 滚动消息到底部
		function scrollMessageToBottom(uuid: string) {
			const messageElement = document.querySelector(`.exec-message-${uuid}`);
			if (messageElement?.scrollHeight) {
				messageElement.scrollTop = messageElement.scrollHeight;
			}
		}

		return {
			state,
			initializeTasks,
			updateTaskStatus,
			toggleTaskMessage,
			updateAutoCleanSetting,
			appendTaskMessage,
			addNewTask,
			removeTask,
			clearAllTasks,
			startNextTask,
			retryTask,
			clearCompletedTasks,
		};
	}
);
